import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';

class Axios {

    instance: AxiosInstance | null = null;

    constructor(config: AxiosRequestConfig) {
        this.instance = axios.create(config);
        this.setInterceptors()
    }

    setInterceptors() {
        this.setRequestInterceptor()
        this.setResponseInterceptor()
    }

    setRequestInterceptor() {
        this.instance!.interceptors.request.use(config => config)
    }

    setResponseInterceptor() {
        this.instance!.interceptors.response.use(response => {
            return new Promise((resolve, reject) => {
                const myResponseData: ResponseData = response.data;
                if (response.status <= 299 && response.status >= 200) {
                    if (myResponseData.code === 200) {
                        resolve(myResponseData.data)
                    } else {
                        reject(myResponseData.message || '系统异常')
                    }
                } else if (response.status === 500) {
                    reject('服务端出现异常');
                } else if (response.status === 403) {
                    reject('请求权限不足')
                } else if (response.status === 404) {
                    reject('请求资源不存在')
                } else if (response.status === 401) {
                    reject('匿名用户')
                } else {
                    reject('未知错误')
                }
            })
        })
    }

    get<T = any>(url: string, data?: any) {
        return new Promise((resolve, reject) => {
            this.instance?.get<ResponseData<T>>(url, data).then(res => {
                resolve(res as T)
            }).catch(error => {
                reject(error);
            })
        })
    }

    post<T = any>(url: string, data?: any) {
        return new Promise((resolve, reject) => {
            this.instance?.post<ResponseData<T>>(url, data).then(res => {
                resolve(res as T)
            }).catch(error => {
                reject(error)
            })
        })
    }

    request<T = any, D = ResponseData<T>>(config: AxiosRequestConfig): Promise<T> {
        return new Promise(async (resolve, reject) => {
            try {
                const result = await this.instance!.request<D>(config);
                resolve(result as T)
            } catch (error) {
                reject(error)
            }
        })
    }
}

export default Axios